package com.ruoyi.web.controller.business;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ZipUtil;
import com.ruoyi.business.domain.TChunkInfo;
import com.ruoyi.business.domain.dto.ModelingManagementFormDTO;
import com.ruoyi.business.domain.vo.UploadResult;
import com.ruoyi.business.service.ChunkService;
import com.ruoyi.business.service.IModelingManagementService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.file.FileInfoUtils;
import com.ruoyi.common.utils.file.FileUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;

/**
 * 上传下载文件
 *
 * @author 洋葱骑士
 * 源码地址：https://gitee.com/luckytuan/fast-loader
 */
@Api("大文件上传")
@RestController
@RequestMapping("/uploader")
public class FileController extends BaseController {

    @Value("${ruoyi.profile}")
    private String uploadFolder;

    @Resource
    private ChunkService chunkService;

    @Autowired
    private IModelingManagementService iModelingManagementService;

    private final Logger logger = LoggerFactory.getLogger(FileController.class);

    /**
     * 上传文件块
     *
     * @param chunk
     * @return
     */
    @ApiOperation("上传文件块")
    @PostMapping("/chunk")
    public AjaxResult uploadChunk(TChunkInfo chunk) {
        MultipartFile file = chunk.getUpfile();
        logger.info("file originName: {}, chunkNumber: {}", file.getOriginalFilename(), chunk.getChunkNumber());
        try {
            byte[] bytes = file.getBytes();
            Path path = Paths.get(FileInfoUtils.generatePath(uploadFolder, chunk.getFilename(), chunk.getChunkNumber(), chunk.getIdentifier()));
            //文件写入指定路径
            Files.write(path, bytes);
            if (chunkService.saveChunk(chunk) < 0) {
                return AjaxResult.error();
            }
        } catch (IOException e) {
            return AjaxResult.error("上传失败");
        }
        return AjaxResult.success();
    }

    @ApiOperation("查询上传文件块")
    @GetMapping("/chunk")
    public UploadResult checkChunk(TChunkInfo chunk, HttpServletResponse response) {
        UploadResult ur = new UploadResult();
        String file = uploadFolder + "/" + chunk.getIdentifier() + "/" + chunk.getFilename();
        //先判断整个文件是否已经上传过了，如果是，则告诉前端跳过上传，实现秒传
        if (FileInfoUtils.fileExists(file)) {
            ur.setSkipUpload(true);
            ur.setLocation(file);
            response.setStatus(HttpServletResponse.SC_OK);
            ur.setMessage("完整文件已存在，直接跳过上传，实现秒传");
            return ur;
        }
        //如果完整文件不存在，则去数据库判断当前哪些文件块已经上传过了，把结果告诉前端，跳过这些文件块的上传，实现断点续传
        ArrayList<Integer> list = chunkService.checkChunk(chunk);
        if (list != null && list.size() > 0) {
            ur.setSkipUpload(false);
            ur.setUploadedChunks(list);
            response.setStatus(HttpServletResponse.SC_OK);
            ur.setMessage("部分文件块已存在，继续上传剩余文件块，实现断点续传");
            return ur;
        }
        return ur;
    }

    @ApiOperation("合并文件块")
    @PostMapping("/mergeFile")
    public AjaxResult mergeFile(@RequestBody ModelingManagementFormDTO formDTO) {
        String rlt = "FALURE";
        //进行文件的合并操作
        String filename = formDTO.getFilename();
        String file = uploadFolder + "/" + formDTO.getIdentifier() + "/" + filename;
        String folder = uploadFolder + "/" + formDTO.getIdentifier();
        String fileSuccess = FileInfoUtils.merge(file, folder, filename);
        int result = 0;
        //文件合并成功后，保存记录至数据库
        if ("200".equals(fileSuccess) || "300".equals(fileSuccess)) {
            File desc = new File(folder + "/" + "unzip");
            if (!desc.exists()) {
                desc.mkdirs();
            }
            File unzip = ZipUtil.unzip(new File(file), desc, CharsetUtil.CHARSET_GBK);
            FileUtils.deleteFile(file);
            String modelingFileUrl =unzip.getPath() + "/" +  filename.replace(".zip", "");
            formDTO.setModelingFileUrl(modelingFileUrl);
            result = iModelingManagementService.updateModelingManagement(formDTO);
        }
        return toAjax(result);
    }
}
